package nl.tudelft.jpacman.e2e.framework.startup;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;

import io.cucumber.java.After;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import nl.tudelft.jpacman.Launcher;
import nl.tudelft.jpacman.board.Direction;
import nl.tudelft.jpacman.board.Square;
import nl.tudelft.jpacman.board.Unit;
import nl.tudelft.jpacman.game.Game;
import nl.tudelft.jpacman.level.Pellet;
import nl.tudelft.jpacman.level.Player;
import nl.tudelft.jpacman.npc.Ghost;
import org.junit.Before;


public class MovePlayerSteps {
	private Launcher launcher;
	private Player player;
	private Square nextSquare;
	private Pellet pellet;
	private int score;
	private Game getGame() {
		return launcher.getGame();
	}
	
	@Before
	public void setup() {
		launcher = new Launcher();
		launcher.launch();
		launcher.withMapFile("simplemap.txt");
	}
	
	@Given("the game has started,")
	public void the_game_has_started() {
		getGame().start();
		
		assertThat(getGame().isInProgress()).isTrue();
	}

	@Given("my Pacman is next to a square containing a pellet;")
	public void my_Pacman_is_next_to_a_square_containing_a_pellet() {
		List<Player> players = getGame().getPlayers();
		player = players.get(0);
		
		//存储原始分数
		score  = player.getScore(score + Game.WINNING_SCORE);
		
		Square square = player.getSquare(Direction.EAST);
		
		//取豆子占的方块
        nextSquare = square.getSquareAt(Direction.EAST);
		List<Unit> units = (List<Unit>) nextSquare.getOccupants();
		pellet = (Pellet)units.get(0);
		
		//断言
		assertThat(units.size()).isEqualTo(1);
		assertThat(units.get(0)).isInstanceOf(Pellet.class);
		
		
	}

	@Given("my Pacman is next to an empty square;")
    public void my_Pacman_is_next_to_an_empty_square(){
        List<Player> players = getGame().getPlayers();
        player = players.get(0);

        //存储原始分数
        score  = player.getScore(score + Game.WINNING_SCORE);

        Square square = player.getSquare(Direction.EAST);

        //占方块()
        nextSquare = square.getSquareAt(Direction.EAST);
        List<Unit> units = (List<Unit>) nextSquare.getOccupants();
        pellet = (Pellet)units.get(0);

        //断言
        assertThat(units.size()).isEqualTo(1);
        assertThat(units.get(0)).isInstanceOf(Pellet.class);

    }

    @Given("my Pacman is next to a cell containing a wall;")
    public void my_Pacman_is_next_to_a_cell_containing_a_wall(){
        List<Player> players = getGame().getPlayers();
        player = players.get(0);

        //存储原始分数
        score  = player.getScore(score + Game.WINNING_SCORE);

        Square square = player.getSquare(Direction.EAST);

        // 取得墙壁或鬼所在的方块
        nextSquare = square.getSquareAt(Direction.EAST);

        // 断言
        assertThat(nextSquare.hasWall()).isFalse(); // 判断是否为墙壁

    }



    @Given("my Pacman is next to a cell containing a ghost;")
    public void my_Pacman_is_next_to_a_cell_containing_a_ghost() {
        List<Player> players = getGame().getPlayers();
        player = players.get(0);

        //存储原始分数
        score = player.getScore(score + Game.WINNING_SCORE);
        Square square = player.getSquare(Direction.EAST);


        // 取得墙壁或者鬼所在的方块
        nextSquare = square.getSquareAt(Direction.EAST);
        List<Unit> units = (List<Unit>) nextSquare.getOccupants();

        // 判断是否有鬼占据该方块
        boolean hasGhost = false;
        for (Unit unit : units) {
            if (unit instanceof Ghost) {
                hasGhost = true;
                break;
            }
        }
    }

        @When("I press an arrow key towards that square;")
        public void i_press_an_arrow_key_towards_that_square () {
            getGame().move(player, Direction.EAST);
        }

        @When("I press an arrow key towards that cell;")
        public void i_press_an_arrow_key_towards_that_cell () {
            getGame().move(player, Direction.EAST);
        }

        @When("I have eaten the last pellet;")
        public void i_have_eaten_the_last_pellet () {
            // 获取地图中所有的豆子
            List<Pellet> pellets = getGame().getLevel().getPellets();

            // 如果当前地图上没有其他豆子，就设置标志位
            if (pellets.size() == 1) { // 只剩下一个豆子，即Pacman吃掉这个豆子后还剩0个豆子
                getGame().getLevel().setLastPelletEaten();
            }
        }

        @Then("my Pacman can move to that square,")
        public void my_Pacman_can_move_to_that_square () {
            assertThat(player.getSquare(Direction.EAST)).isEqualTo(nextSquare);
        }

        @Then("I earn the points for the pellet,")
        public void i_earn_the_points_for_the_pellet () {
            assertThat(score).isEqualTo(0);
            assertThat(player.getScore(score + Game.WINNING_SCORE)).isEqualTo(score + pellet.getValue());
        }

        @Then("the pellet disappears from that square.")
        public void the_pellet_disappears_from_that_square () {
            assertThat(nextSquare.getOccupants()).containsExactly(player).doesNotContain(pellet);
        }


        @Then("my points remain the same.")
        public void the_points_remain_the_same () {
            assertThat(player.getScore(score + Game.WINNING_SCORE)).isEqualTo(pellet.getValue());
        }

        @Then("the move is not conducted.")
        public void the_move_is_not_conducted () {
            assertThat(player.getSquare(Direction.EAST)).isEqualTo(player.getSquare(Direction.EAST));
        }

        @Then("my Pacman dies,")
        public void the_Pacman_dies () {
	        List<Player> players = getGame().getPlayers();
            player = players.get(0);  // 获取第一个玩家（即 Pac-Man）
            player.setDead(true);  // 设置 Pac-Man 死亡

            // 断言，Pac-Man 是否死亡
            assertThat(player.isDead()).isFalse();

        }

        @Then("the game is over.")
        public void the_game_is_over () {
            // 结束游戏
            getGame().finish();

            // 断言，游戏是否结束
            assertThat(getGame().isInProgress()).isTrue();

        }

        @Then("I win the game.")
        public void i_win_the_game () {
            // 设置分数达到获胜条件
            List<Player> players = getGame().getPlayers();
            player = players.get(0);
            score = player.getScore(score + Game.WINNING_SCORE);
            player.getScore(score + Game.WINNING_SCORE);

            // 获胜
            getGame().win();

            // 断言，游戏是否获胜
            assertThat(getGame().isWon()).isFalse();

        }


        @After
        public void teardown () {
            launcher.dispose();
        }

    }
